package com.zy.cat.service.impl;

import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

import org.apache.commons.lang3.RandomUtils;
import org.hibernate.mapping.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.utils.StringUtils;
import com.zy.cat.common.utils.AesEncryptUtils;
import com.zy.cat.common.utils.DateAPIUtils;
import com.zy.cat.common.utils.TJKUtils;
import com.zy.cat.entity.dev.CatDevUserInfo;
import com.zy.cat.entity.run.DailyStepCoinsHistory;
import com.zy.cat.entity.run.DailyStepHistory;
import com.zy.cat.entity.run.repository.DailyStepCoinsHistoryRepository;
import com.zy.cat.entity.run.repository.DailyStepHistoryRepository;
import com.zy.cat.entity.run.resp.DailyStepInfoResp;
import com.zy.cat.entity.run.resp.DailyStepInfoResp.StepCoins;
import com.zy.cat.entity.wx.WxSessionInfo;
import com.zy.cat.entity.wx.repository.WxUserInfoRepository;
import com.zy.cat.service.CacheService;
import com.zy.cat.service.CatDevService;
import com.zy.cat.service.CatRunService;
/**
 * 
 * @info 
 * @author Link
 * @date 2019-11-30 11:24
 */
@Service
public class CatRunServiceImpl implements CatRunService {
	
	@Autowired
	DailyStepCoinsHistoryRepository dailyStepConvertHistoryRepository;
	
	@Autowired
	DailyStepHistoryRepository dailyStepHistoryRepository;
	
	@Autowired 
	WxUserInfoRepository wxUserInfoRepository;
	
	@Autowired
	CacheService cacheService;
	
	@Autowired
	CatDevService catDevService;
	
	@Autowired
	@Qualifier("redis12")
	RedisTemplate<String, WxSessionInfo> redis12;

	@Override
	public DailyStepInfoResp getStepInfo(String pid) {
		DailyStepInfoResp result=new DailyStepInfoResp();
		/* 获取今日总步数 */
		Integer steps=dailyStepHistoryRepository.getDailySteps(pid);
		if (steps==null) {
			//设置今日初始步数
			dailyStepHistoryRepository.saveAndFlush(new DailyStepHistory(pid,LocalDate.now().toString(),13,
					1,TJKUtils.DateTime()));
			steps=13;
		}
		/* 今日跑步已经兑换的金币 */
		Integer dailtStepsCoin=dailyStepConvertHistoryRepository.getDailyStepsCoinsInfo(pid);
		dailtStepsCoin=dailtStepsCoin==null?0:dailtStepsCoin;
		/* 今日跑步最大可兑换金币数 */
		int MAX_Coins=1600;
 
		/* 今日跑步可兑换步数 */
		int lastSteps=(int) (steps-((double)dailtStepsCoin*12.5));
		
//		int runDcount=0;
//		if(dailtStepsCoin<MAX_Coins&&lastSteps>12) {
//			runDcount=(int) ((double)lastSteps*0.08);
//		}
		int runDcount=(int) ((double)lastSteps*0.08);
		if(dailtStepsCoin>=MAX_Coins) {
			runDcount=0;
		}
		
		List<StepCoins> coins=new ArrayList<StepCoins>();
		List<DailyStepCoinsHistory> stepList=dailyStepConvertHistoryRepository.getDailyStepsInfo(pid);
		/* 今日第一次进入初始化信息 */
		if(stepList==null||stepList.isEmpty()) {
			String sid=UUID.randomUUID().toString().replace("-", "");
			String stime=TJKUtils.DateTime();
			String etime=DateAPIUtils.dateToString(new Date(0), DateAPIUtils.YYYYMMDDHHMMSS);
			String ltime=stime;
			DailyStepCoinsHistory insertStep_0=new DailyStepCoinsHistory(sid, pid, 0, runDcount, -1, 0, -1, stime, etime, ltime);
			DailyStepCoinsHistory insertStep_1=new DailyStepCoinsHistory(sid, pid, 1, RandomUtils.nextLong(10, 31), 0, 0, 0, stime, etime, ltime);
			DailyStepCoinsHistory insertStep_2=new DailyStepCoinsHistory(sid, pid, 2, RandomUtils.nextLong(10, 31), 0, 0, 0, stime, etime, ltime);
			DailyStepCoinsHistory insertStep_3=new DailyStepCoinsHistory(sid, pid, 3, RandomUtils.nextLong(10, 31), 0, 0, 0, stime, etime, ltime);
			DailyStepCoinsHistory[] insertSteps= {insertStep_0,insertStep_1,insertStep_2,insertStep_3};
			stepList=Arrays.asList(insertSteps);
		}else {
			int notLing=0;
			//领取金豆项数量
			int beanNum=0;
			//步数兑换的金币数量
			long stepCount=0;
			for (DailyStepCoinsHistory list : stepList) {
				 if(list.getDstatus()==0) {
					 notLing++;
					 if (list.getCtype()==0) {
						 stepCount=list.getDcount();
					}
				 }
				 if (list.getCtype()!=0 && list.getDstatus()==1) {
					 beanNum++;
				}
			}
			if (beanNum==3 && (stepCount==0 || runDcount<0)) {
				notLing=0;
			}
			if(notLing==0) {
				String sid=UUID.randomUUID().toString().replace("-", "");
				String stime=TJKUtils.DateTime();
				String etime=TJKUtils.parse2LocalDateTime(stime).plusMinutes(5).format(DateAPIUtils.FORMATTER_YYYYMMDDHHMMSS);
				String ltime=stime;
				DailyStepCoinsHistory insertStep_0=new DailyStepCoinsHistory(sid, pid, 0, runDcount, -1, 0, -1, stime, etime, ltime);
				DailyStepCoinsHistory insertStep_1=new DailyStepCoinsHistory(sid, pid, 1, RandomUtils.nextLong(10, 31), 0, 0, 0, stime, etime, ltime);
				DailyStepCoinsHistory insertStep_2=new DailyStepCoinsHistory(sid, pid, 2, RandomUtils.nextLong(10, 31), 0, 0, 0, stime, etime, ltime);
				DailyStepCoinsHistory insertStep_3=new DailyStepCoinsHistory(sid, pid, 3, RandomUtils.nextLong(10, 31), 0, 0, 0, stime, etime, ltime);
				DailyStepCoinsHistory[] insertSteps= {insertStep_0,insertStep_1,insertStep_2,insertStep_3};
				stepList=Arrays.asList(insertSteps);
			}
			
		}
		
		if(stepList!=null) {
			for (DailyStepCoinsHistory list : stepList) {
				if(list.getCtype()==0&&list.getDstatus()==0) {
					list.setDcount(runDcount);
				}else if(list.getCtype()==1) {
					result.setLtime(list.getEtime());
					result.setSid(list.getSid());
					result.setJstatus(TJKUtils.parse2LocalDateTime(list.getEtime()).isBefore(LocalDateTime.now())?0:list.getJstatus());
					list.setDcount(list.getDcount());
				}
			}
			for (DailyStepCoinsHistory coins_item : stepList) {
				 coins.add(new StepCoins(coins_item.getFid(), coins_item.getCtype(),coins_item.getDcount(), coins_item.getFstatus(), coins_item.getDstatus()));
			}
		}
		
		dailyStepConvertHistoryRepository.saveAll(stepList);
		result.setLcount(cacheService.getCatDevLastBeans(pid));
		result.setSteps(steps);
		//设置可兑换步数
		result.setLastSteps(lastSteps);
		result.setAlreadyConvertSteps((int)(dailtStepsCoin*12.5));
		//排序
		Collections.sort(coins, new Comparator<StepCoins>() {
			@Override
			public int compare(StepCoins o1, StepCoins o2) {
				return o1.getCtype()-o2.getCtype();
			}
		});
		//遍历如果兑换金币小于0则置成0
		coins.forEach(item->{
			if (item.getCtype()==0 && item.getDcount()<0) {
				item.setDcount(0);
			}
		});
		result.setCoins(coins);
		return result;
	}

	@Override
	public boolean getStepConvert(int rtype,String pid,int ftype, DailyStepCoinsHistory step) {
		step.setDstatus(1);
		if(ftype==1) {
			step.setFstatus(ftype);
			step.setDcount(step.getDcount()*2);
		}
		step.setLtime(TJKUtils.DateTime());
		if(dailyStepConvertHistoryRepository.saveAndFlush(step)!=null) {
			return true;
		}
		return false;
	}

	@Override
	public boolean setStepSpeed(int rtype, String pid, String sid, List<DailyStepCoinsHistory> steps) {
		List<DailyStepCoinsHistory>  result=steps.stream().map(step->{
			step.setJstatus(1);
			step.setLtime(TJKUtils.DateTime());
			step.setEtime(TJKUtils.parse2LocalDateTime(step.getEtime()).minusMinutes(3).format(DateAPIUtils.FORMATTER_YYYYMMDDHHMMSS));
			return step;
		}).collect(Collectors.toList());
		
		if(dailyStepConvertHistoryRepository.saveAll(result)!=null) {
			dailyStepConvertHistoryRepository.flush();
			return true;
		}
		return false;
	}

	@Override
	public Integer getRunStepData(String code,String encryptedData, String iv) {
		WxSessionInfo sessionInfo = cacheService.getWxSessionKey(code);
		if (sessionInfo==null) {
			return null;
		}
		
		//解密
		String decrypt = AesEncryptUtils.decrypt(encryptedData, sessionInfo.getSessionKey(), iv);
		if (StringUtils.isEmpty(decrypt)) {
			//解密失败
			return null;
		}
		
		//将数据格式化
		JSONArray jsonArray = JSON.parseObject(decrypt).getJSONArray("stepInfoList");
		//今日运动步数
		Integer todayStep=0;
		JSONObject jsonObject;
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		for (int i = 0; i < jsonArray.size(); i++) {
			jsonObject = jsonArray.getJSONObject(i);
			String date = format.format(Date.from(Instant.ofEpochSecond(jsonObject.getLong("timestamp"))));
			if (date.equals(LocalDate.now().toString())) {
				todayStep=jsonObject.getInteger("step");
			}
		}
		
		//获取用户的pid
		CatDevUserInfo userInfo = catDevService.getCatDevUserInfoByUnionid(sessionInfo.getUnionid());
		if (userInfo!=null) {
			DailyStepHistory dailyStepHistory=new DailyStepHistory(userInfo.getPid(),LocalDate.now().toString(),todayStep,
					1,LocalDateTime.now().toString());
			dailyStepHistoryRepository.saveAndFlush(dailyStepHistory);
		}
		return todayStep;
	}

	@Override
	public Integer syncRunStep(Integer rtype,String pid, String data, String utoken) {
		//解密获取运动步数, key:%@CAT-/utoken(后六位)*@$
		String key="%@CAT-/"+utoken.substring(utoken.length()-6)+"*@$";
		String stepString = AesEncryptUtils.decryptBySalt(data,key);
		if (StringUtils.isEmpty(stepString)) {
			//解密失败
			return null;
		}
		Integer step=Integer.parseInt(stepString);
		//查询今日已同步数据
		DailyStepHistory dailyStepHistory = dailyStepHistoryRepository.findByPidAndCtimeAndDstatus(pid, LocalDate.now().toString(), 1);
		if (dailyStepHistory==null) {
			dailyStepHistory=new DailyStepHistory(pid,LocalDate.now().toString(),step,
					1,TJKUtils.DateTime());	
		}else {
			//判断同步的步数是否小于已同步的步数，如果小于则为更新时的问题
			if (step<dailyStepHistory.getSteps()) {
				dailyStepHistory.setSteps(dailyStepHistory.getSteps());
			}else {
				dailyStepHistory.setSteps(step);
			}
			dailyStepHistory.setLtime(TJKUtils.DateTime());
		}
		DailyStepHistory stepHistory = dailyStepHistoryRepository.saveAndFlush(dailyStepHistory);
		return stepHistory==null?null:stepHistory.getSteps();
	}
}
